package coveranalyzer.handlers;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;

public class SearchHelper {

	private static SearchHelper instance;

	private SearchEngine fSearchEngine;

	private SearchHelper() {
		fSearchEngine = new SearchEngine();
	}

	public Set<IJavaElement> searchElementReference(IJavaElement elem) {
		SearchPattern pattern = SearchPattern.createPattern(elem,
				IJavaSearchConstants.REFERENCES);
		IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
		List<SearchMatch> matches = search(scope, pattern);
		Set<IJavaElement> rst = new LinkedHashSet<IJavaElement>();
		for (SearchMatch match : matches) {
			rst.add((IJavaElement) match.getElement());
		}
		return rst;
	}

	/**
	 * Invoke java search engine to perform a search operation
	 * 
	 * @param scope
	 * @param pattern
	 * @return a list containing all matched search result
	 */
	public List<SearchMatch> search(IJavaSearchScope scope,
			SearchPattern pattern) {
		SearchRequesterImpl requestor = new SearchRequesterImpl();
		try {
			SearchParticipant[] participants = new SearchParticipant[] { SearchEngine
					.getDefaultSearchParticipant() };
			fSearchEngine.search(pattern, participants, scope, requestor, null);
		} catch (Exception e) {
		}
		return requestor.getResults();
	}

	/**
	 * Implements SearchRequestor for java search engine work, this
	 * implementation will put all search result into a list
	 * 
	 * @author dongxu
	 * 
	 */
	private static class SearchRequesterImpl extends SearchRequestor {

		private List<SearchMatch> results;

		public SearchRequesterImpl() {
			super();
			results = new ArrayList<SearchMatch>();
		}

		@Override
		public void acceptSearchMatch(SearchMatch match) throws CoreException {
			results.add(match);
		}

		public List<SearchMatch> getResults() {
			return results;
		}

	}

	public static SearchHelper create() {
		if (instance == null) {
			instance = new SearchHelper();
		}
		return instance;
	}
}
